package com.nutiteq.fullscreen;

import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;

import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.AlertType;
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.midlet.MIDletStateChangeException;

import com.nutiteq.BasicMapComponent;
import com.nutiteq.cache.CachingChain;
import com.nutiteq.cache.MemoryCache;
import com.nutiteq.cache.RmsCache;
import com.nutiteq.components.WgsPoint;
import com.nutiteq.controls.ControlKeys;
import com.nutiteq.controls.OnScreenZoomControls;
import com.nutiteq.listeners.MapListener;
import com.nutiteq.log.Log;
import com.nutiteq.maps.NutiteqStreamedMap;
import com.nutiteq.ui.DefaultCursor;
import com.nutiteq.ui.DefaultZoomIndicator;
import com.nutiteq.ui.ThreadDrivenPanning;
import com.nutiteq.utils.DummyStarter;
import com.nutiteq.utils.InitializedCanvas;
import com.nutiteq.utils.LogForm;
import com.nutiteq.utils.Utils;

public class MapCanvas extends Canvas implements CommandListener, MapListener, InitializedCanvas {

  private final MapCanvas instance;

  private Image splash;

  private final Timer timer;
  private Thread starter;

  private final BasicMapComponent mapComponent;

  private Command exit;
  private Command fullscreen;
  private Command notifyOk;

  private boolean isFullscreen;
  private boolean initialized;

  
  public MapCanvas() {
    instance = this;

    try {
      splash = Image.createImage("/splash.png");
    } catch (final IOException e) {
      e.printStackTrace();
    }

    timer = new Timer();
    timer.schedule(new TimerTask() {
      public void run() {
        starter = new Thread(new DummyStarter(Fullscreen.instance, instance));
        starter.start();
      }
    }, 3000);
    mapComponent = new BasicMapComponent("abcdtrial", Fullscreen.instance, getWidth(), getHeight(),
        new WgsPoint(24.764580, 59.437420), 5);
    
  }

  public void initialize() {
    mapComponent.setMap(NutiteqStreamedMap.OPENSTREETMAP);
    mapComponent.setPanningStrategy(new ThreadDrivenPanning());

    final MemoryCache memoryCache = new MemoryCache(50 * 1024);
    final RmsCache rmsCache = new RmsCache("ML_NETWORK_CACHE", 64 * 1024, 5);
    mapComponent.setNetworkCache(new CachingChain(new com.nutiteq.cache.Cache[] { memoryCache,
        rmsCache }));

    mapComponent.startMapping();
    if (hasPointerEvents()) {
      mapComponent.setOnScreenZoomControls(new OnScreenZoomControls(Utils
          .createImage(OnScreenZoomControls.DEFAULT_ZOOM_IMAGE)));
    } else {
      mapComponent.setCursor(new DefaultCursor(0xFFFF0000));
    }

    mapComponent.defineControlKey(ControlKeys.MOVE_UP_KEY, -1);
    mapComponent.defineControlKey(ControlKeys.MOVE_DOWN_KEY, -2);
    mapComponent.defineControlKey(ControlKeys.MOVE_LEFT_KEY, -3);
    mapComponent.defineControlKey(ControlKeys.MOVE_RIGHT_KEY, -4);
    mapComponent.defineControlKey(ControlKeys.SELECT_KEY, -5);
    //MPowerPlayer
    mapComponent.defineControlKey(ControlKeys.MOVE_UP_KEY, 38);
    mapComponent.defineControlKey(ControlKeys.MOVE_DOWN_KEY, 40);
    mapComponent.defineControlKey(ControlKeys.MOVE_LEFT_KEY, 37);
    mapComponent.defineControlKey(ControlKeys.MOVE_RIGHT_KEY, 39);
    mapComponent.defineControlKey(ControlKeys.SELECT_KEY, 10);
    //for motorola
    mapComponent.defineControlKey(ControlKeys.MOVE_UP_KEY, KEY_NUM2);
    mapComponent.defineControlKey(ControlKeys.MOVE_DOWN_KEY, KEY_NUM8);
    mapComponent.defineControlKey(ControlKeys.MOVE_LEFT_KEY, KEY_NUM4);
    mapComponent.defineControlKey(ControlKeys.MOVE_RIGHT_KEY, KEY_NUM6);
    mapComponent.defineControlKey(ControlKeys.SELECT_KEY, KEY_NUM5);

    mapComponent.setZoomLevelIndicator(new DefaultZoomIndicator(0, 1));

    mapComponent.setMapListener(this);

    exit = new Command("Exit", Command.EXIT, 0);
    fullscreen = new Command("Fullscreen on", Command.ITEM, 0);
    notifyOk = new Command("OK", Command.OK, 0);

    addCommand(exit);
    addCommand(fullscreen);
    addCommand(LogForm.SHOW_LOG);
    setCommandListener(this);
    initialized = true;
    repaint();
  }

  protected void paint(final Graphics g) {
    if (!initialized) {
      //paint splash
      g.setColor(0xFFFFFFFF);
      g.setClip(0, 0, getWidth(), getHeight());
      g.fillRect(0, 0, getWidth(), getHeight());
      g.drawImage(splash, (getWidth() - splash.getWidth()) / 2,
          (getHeight() - splash.getHeight()) / 2, Graphics.TOP | Graphics.LEFT);
      return;
    }

    g.setClip(0, 0, getWidth(), getHeight());
    mapComponent.paint(g);
  }

  protected void keyPressed(final int keyCode) {
    if (!initialized) {
      return;
    }
    if (isFullscreen && keyCode == KEY_NUM1) {
      commandAction(fullscreen, null);
      return;
    }

    mapComponent.keyPressed(keyCode);
  }

  protected void keyReleased(final int keyCode) {
    if (!initialized) {
      return;
    }
    mapComponent.keyReleased(keyCode);
  }

  protected void keyRepeated(final int keyCode) {
    if (!initialized) {
      return;
    }
    mapComponent.keyRepeated(keyCode);
  }

  protected void pointerDragged(final int x, final int y) {
    if (!initialized) {
      return;
    }
    mapComponent.pointerDragged(x, y);
  }

  protected void pointerPressed(final int x, final int y) {
    if (!initialized) {
      return;
    }
    mapComponent.pointerPressed(x, y);
  }

  protected void pointerReleased(final int x, final int y) {
    if (!initialized) {
      return;
    }
    mapComponent.pointerReleased(x, y);
  }

  public void commandAction(final Command cmd, final Displayable d) {
    if (cmd == exit) {
      mapComponent.stopMapping();
      try {
        Fullscreen.instance.destroyApp(true);
      } catch (final MIDletStateChangeException ignore) {
      }
    } else if (cmd == fullscreen) {
      removeCommand(fullscreen);
      if (isFullscreen) {
        isFullscreen = false;
        fullscreen = new Command("Fullscreen on", Command.ITEM, 0);
      } else {
        isFullscreen = true;
        fullscreen = new Command("Fullscreen off", Command.ITEM, 0);

        final Alert alert = new Alert("Fullscreen",
            "To switch back press key 1. To change map press 5.", null, AlertType.INFO);
        alert.setTimeout(Alert.FOREVER);
        alert.addCommand(notifyOk);
        alert.setCommandListener(this);

        Display.getDisplay(Fullscreen.instance).setCurrent(alert);
      }
      setFullScreenMode(isFullscreen);
      mapComponent.resize(getWidth(), getHeight());
      addCommand(fullscreen);
    } else if (cmd == notifyOk) {
      Display.getDisplay(Fullscreen.instance).setCurrent(this);
    } else if (cmd == LogForm.SHOW_LOG) {
      Display.getDisplay(Fullscreen.instance).setCurrent(
          new LogForm(mapComponent, Fullscreen.instance, this));
    }
  }

  public void mapClicked(final WgsPoint p) {

  }

  public void mapMoved() {

  }

  public void needRepaint(final boolean mapIsComplete) {
    repaint();
  }

  public String getCountryName(String arg0, String arg1) {
    Log.debug("Country name asked for "+arg0+":"+arg1);
    return null;
  }

  public String getPaymentText(int arg0, String arg1) {
    Log.debug("Asked payment text for "+arg0+" "+arg1);
    return null;
  }

  public void paymentStatusChanged(int arg0, String arg1) {
    // TODO Auto-generated method stub
    Log.debug("Payment done status:"+arg0+" text:"+arg1);
    
  }
}
